package WebSocket;

import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class Websocket {

	// BS的I/O处理类
	private ChannelHandler webSocketServerInitializer = new WebSocketServerInitializer();

	private Logger log = LoggerFactory.getLogger(this.getClass());
	// bossGroup中有多个NioEventLoop线程，每个NioEventLoop绑定一个端口，也就是说，如果程序只需要监听1个端口的话，bossGroup里面只需要有一个NioEventLoop线程就行了。

	// 处理io事件的线程
	private static final int BIZTHREADSIZE = 1000;
	private static final EventLoopGroup bossGroup = new NioEventLoopGroup();
	private static final EventLoopGroup workerGroup = new NioEventLoopGroup(BIZTHREADSIZE);

	public void service(int port) {
		try {
			ServerBootstrap bootstrap = new ServerBootstrap();
			bootstrap.group(bossGroup, workerGroup);
			bootstrap.channel(NioServerSocketChannel.class);
			bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
			// TCP_NODELAY是一种算法，为了充分利用带宽，尽可能发送大块数据，减少充斥的小块数据，true是关闭，可以保持高实时性,若开启，减少交互次数，但是时效性相对无法保证
			bootstrap.childOption(ChannelOption.TCP_NODELAY, true);
			bootstrap.childHandler((webSocketServerInitializer));
			ChannelFuture f = bootstrap.bind(port).sync();
			f.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			log.error("netty server is shutdown");
			shutdown();
		}

	}

	// 执行之后关闭
	@PreDestroy
	public static void shutdown() {
		workerGroup.shutdownGracefully();
		bossGroup.shutdownGracefully();
	}

	public ChannelHandler getWebSocketServerInitializer() {
		return webSocketServerInitializer;
	}

	public static void main(String[] args) {
//		new Thread(new Runnable() {
//
//			@Override
//			public void run() {
//				// TODO Auto-generated method stub
//				while (true) {
//					try {
//						Thread.sleep(10000);
//						Handler.sendMessage("[\n" + 
//								"  {\n" + 
//								"    \"id\": 1,\n" + 
//								"    \"name\": \"张三\",\n" + 
//								"    \"age\": 28,\n" + 
//								"    \"email\": \"zhangsan@example.com\",\n" + 
//								"    \"active\": true\n" + 
//								"  },\n" + 
//								"  {\n" + 
//								"    \"id\": 2,\n" + 
//								"    \"name\": \"李四\",\n" + 
//								"    \"age\": 32,\n" + 
//								"    \"email\": \"lisi@example.com\",\n" + 
//								"    \"active\": false\n" + 
//								"  },\n" + 
//								"  {\n" + 
//								"    \"id\": 3,\n" + 
//								"    \"name\": \"王五\",\n" + 
//								"    \"age\": 25,\n" + 
//								"    \"email\": \"wangwu@example.com\",\n" + 
//								"    \"active\": true\n" + 
//								"  }\n" + 
//								"]");
//					} catch (InterruptedException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//
//				}
//			}
//
//		}).start();

		new Websocket().service(5001);

//        System.out.println(StringUtil.bytes2HexString("t:7-F1IqDgmAAG2cQrfKvlKO6LLdDJt9hz4D5gy0AB4KZXD1kaTR6D5yabRqHDV5N7cMYrYTCkyrqHhWdTUWeHLw==".getBytes()).length());
	}
}
